package org.blogwu.learn.multithread.juc.queue;

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.DelayQueue;
import java.util.concurrent.Delayed;
import java.util.concurrent.TimeUnit;

/**
* 延时对列
* @author hyf
* @date 8/2/2020
**/
public class DelayedQueueTest {

    final static DelayQueue q = new DelayQueue();

    public static void main(String[] args) throws InterruptedException {
        final long beginTime=System.currentTimeMillis();

        Thread t1 = new Thread( ()->{
                q.put(new DelayedDTO(System.currentTimeMillis() + 50000L,beginTime));//延迟 5 秒执行
                q.put(new DelayedDTO(System.currentTimeMillis() + 200000L,beginTime));//延迟 2 秒执行
//                q.put(new DelayedDTO(System.currentTimeMillis() + 1000L * 10,beginTime));//延迟 10 秒执行
                System.out.println("t1 执行完毕");
        });

        Thread t2 = new Thread( ()->{
            try {
                q.take();//延迟 2 秒执行
                long end = System.currentTimeMillis();
                System.out.println((end-beginTime)/1000);
//                q.take();//延迟 5 秒执行
//                 end = System.currentTimeMillis();
//                System.out.println((end-beginTime)/1000);
//                q.take();//延迟 10 秒执行
//                 end = System.currentTimeMillis();
//                System.out.println((end-beginTime)/1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });
        Thread t3 = new Thread( ()->{
            try {
                Thread.sleep(2000);
                q.take();//延迟 2 秒执行
                long end = System.currentTimeMillis();
                System.out.println((end-beginTime)/1000);
//                q.take();//延迟 5 秒执行
//                end = System.currentTimeMillis();
//                System.out.println((end-beginTime)/1000);
//                q.take();//延迟 10 秒执行
//                end = System.currentTimeMillis();
//                System.out.println((end-beginTime)/1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });
        t1.start();
        t2.start();
        t3.start();
        t1.join();
        t2.join();
        t3.join();
    }
}

class  DelayedDTO implements Delayed{

    Long s;
    Long beginTime;
    @Override
    public long getDelay(TimeUnit unit) {
        return unit.convert(s - System.currentTimeMillis(), TimeUnit.MILLISECONDS);
    }

    @Override
    public int compareTo(Delayed o) {
        return (int) (this.getDelay(TimeUnit.MILLISECONDS) - o.getDelay(TimeUnit.MILLISECONDS));
    }

    public DelayedDTO(Long s, Long beginTime) {
        this.s = s;
        this.beginTime = beginTime;
    }
}
